package com.tuling.nettyWebSocketClient;

import io.netty.channel.Channel;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelPromise;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.handler.codec.http.FullHttpRequest;
import io.netty.handler.codec.http.FullHttpResponse;
import io.netty.handler.codec.http.websocketx.CloseWebSocketFrame;
import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;
import io.netty.handler.codec.http.websocketx.WebSocketClientHandshaker;
import io.netty.handler.codec.http.websocketx.WebSocketFrame;
import io.netty.util.CharsetUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class WebsocketClientHandler extends SimpleChannelInboundHandler<Object> {
    private static final Logger log = LoggerFactory.getLogger(WebsocketClientHandler.class);

    // 连接处理器
    private final WebSocketClientHandshaker webSocketClientHandshaker;
    // 上下文
    private final WebsocketContext websocketContext;

    // 连接管道
    private Channel channel;

    //netty 提供的数据过程中的数据保证
    private ChannelPromise handshakeFuture;

    public WebsocketClientHandler(WebSocketClientHandshaker webSocketClientHandshaker, WebsocketContext websocketContext) {
        this.webSocketClientHandshaker = webSocketClientHandshaker;
        this.websocketContext = websocketContext;
    }

    @Override
    protected void channelRead0(ChannelHandlerContext ctx, Object msg) throws Exception {
        if (!webSocketClientHandshaker.isHandshakeComplete()) {
            this.handleHttpRequest(msg);
            log.info("websocket已建立连接");
            return;
        }
        if (msg instanceof FullHttpRequest) {
            FullHttpResponse response = (FullHttpResponse) msg;
            throw new IllegalStateException("Unexcepted FullHttpResponse (getStatus=)" + response.status() + ", content=" + response.content().toString(CharsetUtil.UTF_8));
        }
        this.handleWebSocketFrame(msg);
    }

    //处理文本请求
    private void handleWebSocketFrame(Object msg) {
        WebSocketFrame frame = (WebSocketFrame) msg;
        if (frame instanceof TextWebSocketFrame) {
            TextWebSocketFrame textFrame = (TextWebSocketFrame) msg;
            // ...自定义
            this.websocketContext.setResult(textFrame.text());
            this.websocketContext.getLock().release();
        } else if (frame instanceof CloseWebSocketFrame) {
            log.info("接收到关闭帧");
            channel.close();
        }
    }

    // 处理http连接请求
    private void handleHttpRequest(Object msg) {
        webSocketClientHandshaker.finishHandshake(channel, (FullHttpResponse) msg);
        handshakeFuture.setSuccess();
    }

    public ChannelFuture handshakeFuture() {
        return handshakeFuture;
    }

    @Override
    public void handlerAdded(ChannelHandlerContext ctx) throws Exception {
        handshakeFuture = ctx.newPromise();
    }

    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        channel = ctx.channel();
        webSocketClientHandshaker.handshake(channel);
        log.info("建立连接");
    }

    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        log.info("断开连接");
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        log.warn("异常:{},", cause.getMessage(), cause);
    }
}
